﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using KyFileSyncTransfer.Api.Common;
using System.Net.Http.Headers;
using System.Net.Http.Formatting;
using System.Threading.Tasks;

namespace KyFileSyncTransfer.Api.Controllers
{
    public class FilesController : ApiController
    {
        private static string fileSyncDirectory = null;
        private static string logDirectory = null;

        static FilesController()
        {
            fileSyncDirectory = BaseUtility.GetDirectoryFromConfig("FileSyncDirectory");
            logDirectory = BaseUtility.GetDirectoryFromConfig("LogDirectory");
        }

        /// <summary>
        /// 从源文件服务器获取所有文件信息(采用JSON方式)
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("~/api/downfiles")]
        public IHttpActionResult GetFilesForJson()
        {
            if (!Directory.Exists(fileSyncDirectory))
            {
                return BadRequest("同步文件目录不存在或未配置。");
            }

            Dictionary<string, byte[]> files = new Dictionary<string, byte[]>();
            BaseUtility.LoadFileDatas(files, fileSyncDirectory);
            files = files.ToDictionary(kv => kv.Key.Replace(fileSyncDirectory, ""), kv => kv.Value);

            return Json(files);
        }

        /// <summary>
        /// 将所有文件同步保存到目的文件服务器(采用JSON方式)
        /// </summary>
        /// <param name="files"></param>
        /// <returns></returns>
        [HttpPost, Route("~/api/upfiles")]
        public IHttpActionResult SaveFilesForJson([FromBody]IDictionary<string, byte[]> files)
        {
            string requestUrl = HttpContext.Current.Request.Url.ToString();
            var savedErrors = new Dictionary<string, string>();

            if (files == null || !Directory.Exists(fileSyncDirectory))
            {
                return BadRequest();
            }
            foreach (var item in files)
            {
                string file = item.Key;

                string filePath = Path.GetDirectoryName(fileSyncDirectory + file);

                try
                {
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    string saveFilePath = Path.Combine(filePath, Path.GetFileName(file));
                    File.WriteAllBytes(saveFilePath, item.Value);
                }
                catch (Exception ex)
                {
                    savedErrors[file] = string.Format("[{0:yyyy-MM-dd HH:mm:ss}] -请求：{1}同步文件：{2}失败，原因：{3}",
                                    DateTime.Now, requestUrl, file, ex.Message);
                }
            }

            return Json(savedErrors);
        }




        /// <summary>
        /// 从源文件服务器获取所有文件信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage GetFiles()
        {
            if (!Directory.Exists(fileSyncDirectory))
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "同步文件目录不存在或未配置。");
            }

            var response = new HttpResponseMessage(HttpStatusCode.OK);
            var content = new MultipartFormDataContent();
            BaseUtility.CreateMultipartFormDataContent(content, fileSyncDirectory, fileSyncDirectory);
            response.Content = content;
            return response;
        }


        /// <summary>
        /// 将所有文件同步保存到目的文件服务器
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public HttpResponseMessage SaveFiles()
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                return Request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType, "未上传任何文件");
            }

            if (!Directory.Exists(fileSyncDirectory))
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "未找到文件同步上传目录：" + fileSyncDirectory);
            }

            string requestUrl = HttpContext.Current.Request.Url.ToString();
            Dictionary<string, Dictionary<string, string>> savedResult = new Dictionary<string, Dictionary<string, string>>();
            var provider = new MultipartMemoryStreamProvider();
            const string success = "success";
            const string failure = "failure";

            try
            {

                savedResult[success] = new Dictionary<string, string>();
                savedResult[failure] = new Dictionary<string, string>();

                //Request.Content.ReadAsMultipartAsync(provider).Wait();

                Task.Run(async () => await Request.Content.ReadAsMultipartAsync(provider)).Wait();

                foreach (var item in provider.Contents)
                {
                    string fileName = item.Headers.ContentDisposition.FileName;
                    if (string.IsNullOrEmpty(fileName))
                    {
                        continue;
                    }

                    var fileData = item.ReadAsByteArrayAsync().Result;

                    fileName = BaseUtility.ReviseFileName(fileName);
                    string saveFilePath = fileSyncDirectory + fileName;
                    string fileBasePath = Path.GetDirectoryName(saveFilePath);

                    try
                    {
                        if (!Directory.Exists(fileBasePath))
                        {
                            Directory.CreateDirectory(fileBasePath);
                        }
                        File.WriteAllBytes(saveFilePath, fileData);
                        savedResult[success][fileName] = string.Format("[{0:yyyy-MM-dd HH:mm:ss}] - V 请求：{1}同步文件：<{2}>成功。", DateTime.Now, requestUrl, fileName);
                    }
                    catch (Exception ex)
                    {
                        while(ex.InnerException!=null)
                        {
                            ex = ex.InnerException;
                        }

                        savedResult[failure][fileName] = string.Format("[{0:yyyy-MM-dd HH:mm:ss}] - X 请求：{1}同步文件：<{2}>失败，原因：{3}",
                                        DateTime.Now, requestUrl, fileName, ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
            }
            return Request.CreateResponse(HttpStatusCode.OK, savedResult);
        }


        /// <summary>
        /// 移除源文件服务器指定的文件
        /// </summary>
        /// <param name="files"></param>
        /// <returns></returns>
        [HttpPut]
        public IHttpActionResult RemoveFiles([FromBody]IEnumerable<string> files)
        {
            if (files == null || !Directory.Exists(fileSyncDirectory))
            {
                return BadRequest();
            }

            foreach (string file in files)
            {
                string filePath = Path.Combine(fileSyncDirectory, file);
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
            }

            return Ok();
        }

        /// <summary>
        /// 将同步的日志信息写入到源文件服务器LOG文件中
        /// </summary>
        /// <param name="savedErrors"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("~/Api/Files/Log")]
        public IHttpActionResult WriteLog([FromBody] IEnumerable<string> savedResult)
        {
            if (!Directory.Exists(logDirectory))
            {
                return BadRequest("同步日志目录不存在或未配置。");
            }

            BaseUtility.WriteLogToFile(logDirectory, savedResult.ToArray());
            return Ok();
        }

    }
}
